package com.motorhome.api.dao.impl;

import com.motorhome.api.common.dao.DeviceBaseDaoImpl;
import com.motorhome.api.dao.DeviceDao;
import com.motorhome.api.domain.DWRet;
import com.motorhome.api.domain.DevicesData;
import com.motorhome.api.domain.ResDW;
import com.motorhome.api.domain.ResSnapshot;
import com.motorhome.base.dao.Pager;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Repository;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.sql.Blob;
import java.util.DoubleSummaryStatistics;

/**
 * @author: John
 */
@Repository
public class DeviceDaoImpl extends DeviceBaseDaoImpl implements DeviceDao {

    @Override
    public Pager<ResSnapshot> getResList(String deviceId, int page, int pageSize) {

        Pager<DevicesData> data = queryForPageByPageNo("select id,ip,port " +
                        "from mc_devices " +
                        "where sn = ?",
                new Object[]{deviceId},
                new BeanPropertyRowMapper<DevicesData>(DevicesData.class),
                1, 1);

        if(data.getPageSize()>0)
        {
            DevicesData dw = (DevicesData) data.getItems().get(0);
            String id = dw.id;
            return queryForPageByPageNo("select id,resname,longitude,latitude,altitude,termid,timestamp,property " +
                            "from mc_snapshot " +
                            "where termid = ? order by timestamp desc",
                    new Object[]{id},
                    new BeanPropertyRowMapper<ResSnapshot>(ResSnapshot.class),
                    page, pageSize);
        }
        Pager<ResSnapshot> errRet = new Pager<ResSnapshot>();
        return errRet;


    }
    @Override


    public DevicesData getDeviceData(String carid)
    {
        DevicesData ret = new DevicesData();


        Pager<DevicesData> devicesData = queryForPageByPageNo("select id,ip,port " +
                        "from mc_devices " +
                        "where sn = ?",
                new Object[]{carid},
                new BeanPropertyRowMapper<DevicesData>(DevicesData.class),
                1, 1);

        if(devicesData.getPageSize()>0) {

            ret = devicesData.getItems().get(0);
            return ret;
        }
        return ret;
    }



    @Override
    public DWRet getDW(String carid)
    {
        DWRet ret = new DWRet();
        ret.latitude = 0.00;
        ret.longitude = 0.00;

        Pager<DevicesData> devicesData = queryForPageByPageNo("select id,ip,port " +
                        "from mc_devices " +
                        "where sn = ?",
                new Object[]{carid},
                new BeanPropertyRowMapper<DevicesData>(DevicesData.class),
                1, 1);

        if(devicesData.getPageSize()>0) {

            DevicesData devData = (DevicesData) devicesData.getItems().get(0);
            String id = devData.id;
            try {

                String sql = "select data,addtime from mc_gps where termid = ? order by addtime desc";

                Pager<ResDW> data = queryForPageByPageNo(sql, new Object[]{id}, new BeanPropertyRowMapper<ResDW>(ResDW.class), 1, 1);


                if (data.getPageSize() > 0) {
                    ResDW dw = (ResDW) data.getItems().get(0);
                    byte[] byteData = blobToBytes(dw.data);

                    double lat = bytes2Double(byteData, 0);
                    double lon = bytes2Double(byteData, 4);

                    Double i_lat = Double.valueOf(byte2int(byteData, 0, 4)) / 1000000;
                    Double i_lon = Double.valueOf(byte2int(byteData, 4, 4)) / 1000000;


                    ret.latitude = i_lat;
                    ret.longitude = i_lon;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return ret;
    }

    private byte[] blobToBytes(Blob blob) {

        BufferedInputStream is = null;

        try {

            is = new BufferedInputStream(blob.getBinaryStream());

            byte[] bytes = new byte[(int) blob.length()];

            int len = bytes.length;

            int offset = 0;

            int read = 0;

            while (offset < len && (read = is.read(bytes, offset, len - offset)) >= 0) {

                offset += read;

            }

            return bytes;

        } catch (Exception e) {

            return null;

        } finally {

            try {

                is.close();

                is = null;

            } catch (IOException e) {

                return null;

            }

        }

    }

    public  double bytes2Double(byte[] arr,int num )
    {
        long value = 0;
        for (int i = 0; i < 4; i++)
        {
            value |= ((long) (arr[num+i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }

    public  int byte2int(byte[] data,int count,int len) {
        int res = 0;
        switch(len) {
            case 1:{
                res = res |data[0];
                return res;
            }
            case 2:{
                res = res |data[1];
                res = res << 8;
                res = res |data[0];
                return res;
            }
            case 3:{
                res = res |data[2];
                res = res << 8;
                res = res |data[1];
                res = res << 8;
                res = res |data[0];
                return res;
            }
            case 4:{
//                res = res | data[count+3];
//                res = res << 8;
//                res = res | data[count+2];
//                res = res << 8;
//                res = res | data[count+1];
//                res = res << 8;
//                res = res | data[count+0];

                res =  (data[count+3] << 24) | (data[count+2] & 0xFF) << 16 | (data[count+1] & 0xFF) << 8 | (data[count+0] & 0xFF);
//                 res =  (data[count+0]&0xff)<<24
//                        | (data[count+1]&0xff)<<16
//                        | (data[count+2]&0xff)<<8
//                        | (data[count+3]&0xff);

                return res;
            }
            default:return res;
        }
    }



}
